package com.css.bjdt_report.report.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONException;
import org.json.JSONObject;
import org.nutz.dao.sql.Criteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.css.bjdt_report.report.entity.RptTemplateCalc;
import com.css.bjdt_report.report.service.ReportCalcService;
import com.css.bjdt_report.util.JsonResult;
import com.css.bjdt_report.util.PropertyFilter;

@Controller
@RequestMapping(value = "/reportTemplateCountController")
public class ReportTemplateCountController {

	@Autowired
	private ReportCalcService reportCalcService;

	// 将每一个字母都塞进MAP里，然后未来通过字母可以取得对应的列号
	public static String[] letterArray = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O",
			"P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "AA", "AB", "AC", "AD", "AE", "AF", "AG", "AH",
			"AI" };
	public static Map<String, String> numToLetterMap = new HashMap<String, String>();
	public static Map<String, String> letterToNumMap = new HashMap<String, String>();

	static void classLoad() {
		for (int a = 0; a < letterArray.length; a++) {
			numToLetterMap.put(letterArray[a], (a + 1) + "");
			letterToNumMap.put((a + 1) + "", letterArray[a]);
		}
	}

	@RequestMapping(value = "/saveHangCount", method = RequestMethod.POST)
	public String saveHangCount(RptTemplateCalc rptTemplateCalc, Model model) {
		boolean isTureCalc = false;
		String countFormulaRow = rptTemplateCalc.getCalcFormulaShow();
		// 先去掉所有空格
		countFormulaRow = countFormulaRow.replaceAll("\r|\n|\t", "");
		countFormulaRow = countFormulaRow.replace(" ", "");
		String countFormulaAll = "";

		// 先判断是否有波浪线，如果有波浪线，说明是从多少行到多少行，例如2~5，要转换为2行+3行+4行+5行
		if (countFormulaRow.indexOf("~") > 0) {
			String waveString[] = countFormulaRow.split("~");
			for (int a = 0; a < waveString.length; a++) {
				if (a + 1 == waveString.length) {
					break;
				}
				String startStr = getNumStart(waveString[a]);
				String endStr = getNumEnd(waveString[a + 1]);
				// 算出开始和结束的差值，并进行循环，补全破浪线中的数字
				String middleStr = "";
				for (int b = Integer.parseInt(startStr); b < Integer.parseInt(endStr) + 1; b++) {
					middleStr += b + "+";
				}
				countFormulaRow = countFormulaRow.replace(startStr + "~" + endStr,
						middleStr.substring(0, middleStr.length() - 1));
			}
		}

		String[] countEquals = countFormulaRow.split("=");
		// 如果通过=号截取的字符串数组的长度等于2，说明该公式有一个等号，如果不等于2，说明该公式可能没等号或者有2个以上等号，该公式不正确
		if (countEquals.length == 2) {
			// 做最普通的公式转换，例如1=2+3，将转换为1行=2行+3行
			String countFormulaRowRight = countEquals[1];
			String countFormulaRowLeft = countEquals[0];
			countFormulaRowLeft = countFormulaRowLeft.replace(countFormulaRowLeft, countFormulaRowLeft + "行");
			String[] array = countFormulaRowRight.split("[\\+\\-\\*/]");
			for (String s : array) {
				countFormulaRowRight = countFormulaRowRight.replaceFirst(s, s + "行");
			}
			countFormulaAll = countFormulaRowLeft + "=" + countFormulaRowRight;
			List<String> strList = new ArrayList<String>();
			strList.add(countFormulaAll);
			rptTemplateCalc.setCalcFormula(countFormulaAll);
			rptTemplateCalc.setCalcFormulaShow(countFormulaAll);
			rptTemplateCalc.setCalcType("1");
			reportCalcService.insert(rptTemplateCalc);
			isTureCalc = true;
		}
		if (isTureCalc) {
			model.addAttribute("message", "操作成功");
		} else {
			model.addAttribute("message", "公式不正确，请重新输入");
		}
		model.addAttribute("rptTemplateCalc", rptTemplateCalc);
		return "report-design/report-template-customized-hang-input";
	}

	//通过报表的ID，获取行条件
	@ResponseBody
	@RequestMapping(value = "/getCounthangByTemplateId/{templateId}")
	public Map getCounthangByTemplateId(@PathVariable String templateId, HttpServletRequest request,
			@RequestParam(value = "pageNum") int pageNum, @RequestParam(value = "pageSize") int pageSize,
			@RequestParam(value = "sortname") String sortname, @RequestParam(value = "sortorder") String sortorder) {
		Criteria cnd = PropertyFilter.cri(request);
		cnd.where().and("TEMPLATE_ID", "=", templateId).and("CALC_TYPE", "=", "1");
		cnd.getOrderBy().asc("ORDER_ID");

		return reportCalcService.queryPage(cnd, pageNum, pageSize);
	}

	//通过报表的ID，获取行条件
	@ResponseBody
	@RequestMapping(value = "/getCountLieByTemplateId/{templateId}")
	public Map getCountLieByTemplateId(@PathVariable String templateId, HttpServletRequest request,
			@RequestParam(value = "pageNum") int pageNum, @RequestParam(value = "pageSize") int pageSize,
			@RequestParam(value = "sortname") String sortname, @RequestParam(value = "sortorder") String sortorder) {
		Criteria cnd = PropertyFilter.cri(request);
		cnd.where().and("TEMPLATE_ID", "=", templateId).and("CALC_TYPE", "=", "2");
		cnd.getOrderBy().asc("ORDER_ID");

		return reportCalcService.queryPage(cnd, pageNum, pageSize);
	}

	@RequestMapping(value = "/saveLieCount", method = RequestMethod.POST)
	public String saveLieCount(RptTemplateCalc rptTemplateCalc, Model model) {
		classLoad();
		String countFormulaCol = rptTemplateCalc.getCalcFormulaShow();
		// 先去掉所有空格
		countFormulaCol = countFormulaCol.replaceAll("\r|\n|\t", "");
		countFormulaCol = countFormulaCol.replace(" ", "");
		String[] array = countFormulaCol.split("[\\+\\-\\*\\~\\=/]");
		String countFormulaAll = "";
		// 先把列公式从字母转成数字的
		for (String letterStr : array) {
			String numStr = numToLetterMap.get(letterStr.toUpperCase());
			countFormulaCol = countFormulaCol.replaceFirst(letterStr, numStr);
		}

		// 先判断是否有波浪线，如果有波浪线，说明是从多少行到多少行，例如B~D，要转换为B+C+D
		if (countFormulaCol.indexOf("~") > 0) {
			String waveString[] = countFormulaCol.split("~");
			for (int a = 0; a < waveString.length; a++) {
				if (a + 1 == waveString.length) {
					break;
				}
				String startStr = getNumStart(waveString[a]);
				String endStr = getNumEnd(waveString[a + 1]);
				// 算出开始和结束的差值，并进行循环，补全破浪线中的数字
				String middleStr = "";
				for (int b = Integer.parseInt(startStr); b < Integer.parseInt(endStr) + 1; b++) {
					middleStr += b + "+";
				}
				countFormulaCol = countFormulaCol.replace(startStr + "~" + endStr,
						middleStr.substring(0, middleStr.length() - 1));
			}
		}

		// 将公式A=B+C+D转换成A列=B列+C列+D列
		String[] countFormulaColShowArray = countFormulaCol.split("[\\+\\-\\*\\~\\=/]");
		String countFormulaColShow = countFormulaCol;
		for (String str : countFormulaColShowArray) {
			String letterStr = letterToNumMap.get(str);
			countFormulaColShow = countFormulaColShow.replaceFirst(str, letterStr + "列");
		}

		String[] countEquals = countFormulaCol.split("=");
		// 如果通过=号截取的字符串数组的长度等于2，说明该公式有一个等号，如果不等于2，说明该公式可能没等号或者有2个以上等号，该公式不正确
		if (countEquals.length == 2) {
			// 做最普通的公式转换，例如1=2+3，将转换为1列=2列+3列
			String countFormulaColRight = countEquals[1];
			String countFormulaColLeft = countEquals[0];
			countFormulaColLeft = countFormulaColLeft.replace(countFormulaColLeft, countFormulaColLeft + "列");
			String[] array1 = countFormulaColRight.split("[\\+\\-\\*/]");
			for (String s : array1) {
				countFormulaColRight = countFormulaColRight.replaceFirst(s, s + "列");
			}
			countFormulaAll = countFormulaColLeft + "=" + countFormulaColRight;
			List<String> strList = new ArrayList<String>();
			strList.add(countFormulaAll);
			strList.add(countFormulaColShow);
			rptTemplateCalc.setCalcFormula(countFormulaAll);
			rptTemplateCalc.setCalcFormulaShow(countFormulaColShow);
			rptTemplateCalc.setCalcType("2");
			reportCalcService.insert(rptTemplateCalc);
		}
		model.addAttribute("message", "操作成功");
		return "report-design/report-template-customized-lie-input";
	}

	@RequestMapping(value = "/upHangCount", method = RequestMethod.POST)
	public String upHangCount(RptTemplateCalc rptTemplateCalc, Model model) {
		RptTemplateCalc rpt = reportCalcService.getReportCalcById(rptTemplateCalc.getCalcId());
		rpt.setOrderId(rptTemplateCalc.getOrderId());
		rpt.setAreaTemporaryId(rptTemplateCalc.getAreaTemporaryId());
		reportCalcService.update(rpt);
		model.addAttribute("message", "操作成功");
		return "report-design/report-template-customized-hang-input";

	}

	@RequestMapping(value = "/upLieCount", method = RequestMethod.POST)
	public String upLieCount(RptTemplateCalc rptTemplateCalc, Model model) {
		RptTemplateCalc rpt = reportCalcService.getReportCalcById(rptTemplateCalc.getCalcId());
		rpt.setOrderId(rptTemplateCalc.getOrderId());
		rpt.setAreaTemporaryId(rptTemplateCalc.getAreaTemporaryId());
		reportCalcService.update(rpt);
		model.addAttribute("message", "操作成功");
		return "report-design/report-template-customized-lie-input";

	}

	@RequestMapping("/preHangCreate1/{templateId}")
	public String preHangCreate1(@PathVariable String templateId, Model model) {
		model.addAttribute("templateId", templateId);
		return "report-design/report-template-customized-hang-input";
	}

	@RequestMapping("/preLieCreate1/{templateId}")
	public String preLieCreate1(@PathVariable String templateId, Model model) {
		model.addAttribute("templateId", templateId);
		return "report-design/report-template-customized-lie-input";
	}

	@RequestMapping("/preHangUpdate/{calcId}")
	public String preHangUpdate(@PathVariable String calcId, Model model) {
		RptTemplateCalc rptTemplateCalc = reportCalcService.getReportCalcById(calcId);
		model.addAttribute("rptTemplateCalc", rptTemplateCalc);
		model.addAttribute("calcFormulaShow", rptTemplateCalc.getCalcFormulaShow());
		return "report-design/report-template-customized-hang-edit";
	}

	@ResponseBody
	@RequestMapping(value = "/deleteCount/{calcId}", method = RequestMethod.POST)
	public String deleteTemplateConditionById(@PathVariable String calcId) {
		try {
			reportCalcService.delete(calcId);
			return "success";
		} catch (Exception e) {
			return "false";
		}

	}

	@RequestMapping("/preLieUpdate/{calcId}")
	public String preLieUpdate(@PathVariable String calcId, Model model) {
		RptTemplateCalc rptTemplateCalc = reportCalcService.getReportCalcById(calcId);
		model.addAttribute("rptTemplateCalc", rptTemplateCalc);
		model.addAttribute("calcFormulaShow", rptTemplateCalc.getCalcFormulaShow());
		return "report-design/report-template-customized-lie-edit";
	}

	// 行计算公式转换
	@ResponseBody
	@RequestMapping(value = "/countFormulaRowChange/{countFormulaRow}")
	public List<String> countFormulaRowChange(@PathVariable String countFormulaRow, @PathVariable String templateId,
			@PathVariable Integer orderId, HttpServletResponse response) {
		response.setContentType("text/html;charset=utf-8");
		// 先去掉所有空格
		countFormulaRow = countFormulaRow.replace(" ", "");
		String countFormulaAll = "";

		// 先判断是否有波浪线，如果有波浪线，说明是从多少行到多少行，例如2~5，要转换为2行+3行+4行+5行
		if (countFormulaRow.indexOf("~") > 0) {
			String waveString[] = countFormulaRow.split("~");
			for (int a = 0; a < waveString.length; a++) {
				if (a + 1 == waveString.length) {
					break;
				}
				String startStr = getNumStart(waveString[a]);
				String endStr = getNumEnd(waveString[a + 1]);
				// 算出开始和结束的差值，并进行循环，补全破浪线中的数字
				String middleStr = "";
				for (int b = Integer.parseInt(startStr); b < Integer.parseInt(endStr) + 1; b++) {
					middleStr += b + "+";
				}
				countFormulaRow = countFormulaRow.replace(startStr + "~" + endStr,
						middleStr.substring(0, middleStr.length() - 1));
			}
		}

		String[] countEquals = countFormulaRow.split("=");
		// 如果通过=号截取的字符串数组的长度等于2，说明该公式有一个等号，如果不等于2，说明该公式可能没等号或者有2个以上等号，该公式不正确
		if (countEquals.length == 2) {
			// 做最普通的公式转换，例如1=2+3，将转换为1行=2行+3行
			String countFormulaRowRight = countEquals[1];
			String countFormulaRowLeft = countEquals[0];
			countFormulaRowLeft = countFormulaRowLeft.replace(countFormulaRowLeft, countFormulaRowLeft + "行");
			String[] array = countFormulaRowRight.split("[\\+\\-\\*/]");
			for (String s : array) {
				countFormulaRowRight = countFormulaRowRight.replaceFirst(s, s + "行");
			}
			countFormulaAll = countFormulaRowLeft + "=" + countFormulaRowRight;
			List<String> strList = new ArrayList<String>();
			strList.add(countFormulaAll);
			return strList;
		} else {
			return null;
		}

	}

	public String getNumStart(String formula) {
		String[] array = formula.split("[\\+\\-\\*/]");
		int a = array.length;
		return array[a - 1];
	}

	public String getNumEnd(String formula) {
		String[] array = formula.split("[\\+\\-\\*/]");
		return array[0];
	}

	// 列计算公式转换
	@ResponseBody
	@RequestMapping(value = "/countFormulaColChange/{countFormulaCol}")
	public List<String> countFormulaColChange(@PathVariable String countFormulaCol, @PathVariable String templateId,
			@PathVariable Integer orderId, HttpServletResponse response) {
		response.setContentType("text/html;charset=utf-8");
		classLoad();
		// 先去掉所有空格
		countFormulaCol = countFormulaCol.replace(" ", "");
		String[] array = countFormulaCol.split("[\\+\\-\\*\\~\\=/]");
		String countFormulaAll = "";
		// 先把列公式从字母转成数字的
		for (String letterStr : array) {
			String numStr = numToLetterMap.get(letterStr.toUpperCase());
			countFormulaCol = countFormulaCol.replaceFirst(letterStr, numStr);
		}

		// 先判断是否有波浪线，如果有波浪线，说明是从多少行到多少行，例如B~D，要转换为B+C+D
		if (countFormulaCol.indexOf("~") > 0) {
			String waveString[] = countFormulaCol.split("~");
			for (int a = 0; a < waveString.length; a++) {
				if (a + 1 == waveString.length) {
					break;
				}
				String startStr = getNumStart(waveString[a]);
				String endStr = getNumEnd(waveString[a + 1]);
				// 算出开始和结束的差值，并进行循环，补全破浪线中的数字
				String middleStr = "";
				for (int b = Integer.parseInt(startStr); b < Integer.parseInt(endStr) + 1; b++) {
					middleStr += b + "+";
				}
				countFormulaCol = countFormulaCol.replace(startStr + "~" + endStr,
						middleStr.substring(0, middleStr.length() - 1));
			}
		}

		// 将公式A=B+C+D转换成A列=B列+C列+D列
		String[] countFormulaColShowArray = countFormulaCol.split("[\\+\\-\\*\\~\\=/]");
		String countFormulaColShow = countFormulaCol;
		for (String str : countFormulaColShowArray) {
			String letterStr = letterToNumMap.get(str);
			countFormulaColShow = countFormulaColShow.replaceFirst(str, letterStr + "列");
		}

		String[] countEquals = countFormulaCol.split("=");
		// 如果通过=号截取的字符串数组的长度等于2，说明该公式有一个等号，如果不等于2，说明该公式可能没等号或者有2个以上等号，该公式不正确
		if (countEquals.length == 2) {
			// 做最普通的公式转换，例如1=2+3，将转换为1列=2列+3列
			String countFormulaColRight = countEquals[1];
			String countFormulaColLeft = countEquals[0];
			countFormulaColLeft = countFormulaColLeft.replace(countFormulaColLeft, countFormulaColLeft + "列");
			String[] array1 = countFormulaColRight.split("[\\+\\-\\*/]");
			for (String s : array1) {
				countFormulaColRight = countFormulaColRight.replaceFirst(s, s + "列");
			}
			countFormulaAll = countFormulaColLeft + "=" + countFormulaColRight;
			List<String> strList = new ArrayList<String>();
			strList.add(countFormulaAll);
			strList.add(countFormulaColShow);
			return strList;
		} else {
			return null;
		}
	}

	@ResponseBody
	@RequestMapping(value = "/saveCountFormula/{templateId}", method = RequestMethod.POST)
	public void saveCountFormula(@PathVariable String templateId,
			@RequestParam(value = "hangCountFormula") String hangCountFormula,
			@RequestParam(value = "lieCountFormula") String lieCountFormula, Model model) {
		reportCalcService.deleteByTemplateId(templateId);
		List<RptTemplateCalc> hangjisuanList = hangjisuanJson(hangCountFormula, templateId);
		List<RptTemplateCalc> liejisuanList = liejisuanJson(lieCountFormula, templateId);
		reportCalcService.insertList(hangjisuanList);
		reportCalcService.insertList(liejisuanList);
	}

	// 传进入行计算的JSON，将该JSON转换成LIST
	public List<RptTemplateCalc> hangjisuanJson(String hangCountFormula, String templateId) {
		try {
			List<RptTemplateCalc> rptTemplateCalcList = new ArrayList<RptTemplateCalc>();
			JsonResult jsonResult = new JsonResult();
			Map<String, String> map = jsonResult.jsonToString(hangCountFormula);
			Set<String> key = map.keySet();
			for (String strKey : key) {
				String strJson = "{" + map.get(strKey) + "}";
				JSONObject jobj = new JSONObject(strJson);
				RptTemplateCalc rptTemplateCalc = new RptTemplateCalc();
				rptTemplateCalc.setTemplateId(templateId);
				rptTemplateCalc.setCalcFormula(jobj.getString("gongshi"));
				rptTemplateCalc.setCalcType(jobj.getString("jisuantype"));
				rptTemplateCalc.setOrderId(Integer.valueOf(jobj.getString("orderId")));
				rptTemplateCalcList.add(rptTemplateCalc);
			}
			return rptTemplateCalcList;
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	// 传进入列计算的JSON，将该JSON转换成LIST
	public List<RptTemplateCalc> liejisuanJson(String lieCountFormula, String templateId) {
		try {
			List<RptTemplateCalc> rptTemplateCalcList = new ArrayList<RptTemplateCalc>();
			JsonResult jsonResult = new JsonResult();
			Map<String, String> map = jsonResult.jsonToString(lieCountFormula);
			Set<String> key = map.keySet();
			for (String strKey : key) {
				String strJson = "{" + map.get(strKey) + "}";
				JSONObject jobj = new JSONObject(strJson);
				RptTemplateCalc rptTemplateCalc = new RptTemplateCalc();
				rptTemplateCalc.setTemplateId(templateId);
				rptTemplateCalc.setCalcFormula(jobj.getString("gongshiReal"));
				rptTemplateCalc.setCalcFormulaShow(jobj.getString("gongshiShow"));
				rptTemplateCalc.setCalcType(jobj.getString("jisuantype"));
				rptTemplateCalc.setOrderId(Integer.valueOf(jobj.getString("orderId")));
				rptTemplateCalcList.add(rptTemplateCalc);
			}
			return rptTemplateCalcList;
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	// 根据报表的ID获得行列的所有计算公式
	@ResponseBody
	@RequestMapping(value = "/loadCountFormula/{templateId}")
	public List<RptTemplateCalc> loadCountFormula(@PathVariable String templateId) {
		return reportCalcService.queryAllRptTemplateCalcByTemplateId(templateId);
	}
}
